package dp.mobile.entity.generator;

import java.util.ArrayList;
import org.w3c.dom.Node;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import dp.mobile.glwrapper.GLTexture;
import dp.mobile.glwrapper.GameRenderer;
import dp.mobile.system.Utilities;
import dp.mobile.system.XMLReader;

public class GeneratorFactory {
	private static final String TAG = "Generator Factory";
	
	public class GeneratorAttribute {
		private GeneratorAttribute() {
			mLevel 			= 0;
			mUpgradeTime 	= 0;
			mValue 			= 0;
			mWorth 	= new int[] {0, 0, 0};
		}
		
		public GeneratorAttribute(Node root) {
			this();
			
			if (root.getAttributes().getNamedItem("level") != null)
				mLevel = Integer.parseInt(root.getAttributes().getNamedItem("level").getNodeValue());
			
			int childCount = root.getChildNodes().getLength();
			for (int i = 0; i < childCount; ++i) {
				Node child = root.getChildNodes().item(i);
				if (child.getNodeType() == Node.TEXT_NODE) continue;
				
				String tag 		= child.getNodeName();
				String value	= child.getFirstChild().getNodeValue();
				
				if (tag.equals("time"))			mUpgradeTime 	= Integer.parseInt(value);
				else if (tag.equals("value"))	mValue			= Integer.parseInt(value);
				else if (tag.equals("cost")) {
					int grandChildCount = child.getChildNodes().getLength();
					for (int j = 0; j < grandChildCount; ++j) {
						Node cost = child.getChildNodes().item(j);
						/// TODO: might change because might use electricity
						if (!cost.getNodeName().equals("component")) continue;
						
						int componentNum = Integer.parseInt(cost.getAttributes().getNamedItem("type").getNodeValue());
						mWorth[componentNum] = Integer.parseInt(cost.getFirstChild().getNodeValue());
					}
				}
			}
		}
		
		public int getLevel() {
			return mLevel;
		}
		
		public int getUpgradeTime() {
			return mUpgradeTime;
		}
		
		public float getValue() {
			return mValue;
		}
		
		public int getWorth(int num) {
			return mWorth[num];
		}
		
		private int mLevel;
		private int mUpgradeTime;
		private float mValue;
		private int[] mWorth;
	}
	
	protected GeneratorFactory() {
		mBaseBuildCost		= 0;
		mName				= null;
		mPowerUpgrades 		= new ArrayList<GeneratorAttribute>();
		mRangeUpgrades		= new ArrayList<GeneratorAttribute>();
		mVoltageUpgrades	= new ArrayList<GeneratorAttribute>();
		
		//Load Generator file
		Node root = XMLReader.instance().parseXML(Utilities.GENDATA_FILE);
		//For each child
		int childCount = root.getChildNodes().getLength();
		int grandChildCount;
		for (int i = 0; i < childCount; i++) {
			//Get child
			Node child = root.getChildNodes().item(i);
			if (child.getNodeType() == Node.TEXT_NODE) continue;
			
			String tag 		= child.getNodeName();
			String value 	= child.getFirstChild().getNodeValue();
			
			if (tag.equals("build-cost")) 			mBaseBuildCost 		= Integer.parseInt(value);
			else if (tag.equals("regen"))			mBaseRegen			= Integer.parseInt(value);
			else if (tag.equals("dismantle-cost"))	mBaseDismantleCost	= Integer.parseInt(value);
			else if (tag.equals("dismantle-time"))	mBaseDismantleTime	= Integer.parseInt(value);
			else if (tag.equals("transfer-time"))	mBaseTransferTime	= Integer.parseInt(value);
			else if (tag.equals("name"))			mName				= value;
			else if (tag.equals("regen-time"))		mBaseRegenTime 		= Integer.parseInt(value);
			else if (tag.equals("image"))	{
				mBaseImage		= GameRenderer.instance().allocateTexture(Utilities.GEN_FOLDER + "/" + value + ".png");
				//mBaseIcon		= BitmapFactory.decodeFile(Utilities.GEN_FOLDER + "/" + value + "-icon.png");
				mBaseIcon		= BitmapFactory.decodeFile(Utilities.GEN_FOLDER + "/" + value + ".png");
			}
			else if (tag.equals("powers")) {
				grandChildCount = child.getChildNodes().getLength();
				for (int j = 0; j < grandChildCount; ++j)
					if (child.getChildNodes().item(j).getNodeName().equals("power"))
						mPowerUpgrades.add(new GeneratorAttribute(child.getChildNodes().item(j)));
			}
			else if (tag.equals("ranges")) {
				grandChildCount = child.getChildNodes().getLength();
				for (int j = 0; j < grandChildCount; ++j)
					if (child.getChildNodes().item(j).getNodeName().equals("range"))
						mRangeUpgrades.add(new GeneratorAttribute(child.getChildNodes().item(j)));
			}
			else if (tag.equals("voltages")) {
				grandChildCount = child.getChildNodes().getLength();
				for (int j = 0; j < grandChildCount; ++j)
					if (child.getChildNodes().item(j).getNodeName().equals("voltage"))
						mVoltageUpgrades.add(new GeneratorAttribute(child.getChildNodes().item(j)));
			}
		}
	}
	
	public synchronized static GeneratorFactory instance() {
		if (sInstance == null) {
            sInstance = new GeneratorFactory();
        }
		
        return sInstance;
	}
	
	public GeneratorData getBaseGenerator() {
		if (sBaseGenerator == null)
			sBaseGenerator = new GeneratorData(mBaseRegen, mBaseRegenTime, mBaseImage, getPowerUpgrade(1), getRangeUpgrade(1), getVoltageUpgrade(1));
		
		return sBaseGenerator;
	}
	
	public int getBaseBuildCost() {
		return mBaseBuildCost;
	}
	
	public int getBaseDismantleCost() {
		return mBaseDismantleCost;
	}
	
	public int getBaseDismantleTime() {
		return mBaseDismantleTime;
	}
	
	public int getBaseTransferTime() {
		return mBaseTransferTime;
	}
	
	public int getBaseRegen() {
		return mBaseRegen;
	}
	
	public int getBaseRegenTime() {
		return mBaseRegenTime;
	}

	public String getName() {
		return mName;
	}
	
	public GLTexture getImage () {
		return mBaseImage;
	}
	
	public Bitmap getIcon() {
		return mBaseIcon;
	}
	
	public GeneratorData getGeneratorData(int powerLevel, int rangeLevel, int voltageLevel) {
		if (powerLevel > mPowerUpgrades.size()) return null;
		if (rangeLevel > mRangeUpgrades.size()) return null;
		if (voltageLevel > mVoltageUpgrades.size()) return null;
		
		return new GeneratorData(mBaseRegen * (powerLevel + rangeLevel + voltageLevel - 2), mBaseRegenTime, mBaseImage, 
				getPowerUpgrade(powerLevel), getRangeUpgrade(rangeLevel), getVoltageUpgrade(voltageLevel));
	}
	
	GeneratorAttribute getPowerUpgrade(int level) {
		return mPowerUpgrades.get(level - 1);
	}
	
	GeneratorAttribute getRangeUpgrade(int level) {
		return mRangeUpgrades.get(level - 1);
	}
	
	GeneratorAttribute getVoltageUpgrade(int level) {
		return mVoltageUpgrades.get(level - 1);
	}
	
	private static GeneratorFactory sInstance = null;	
	private static GeneratorData	sBaseGenerator = null;
	
	private int mBaseBuildCost;
	private int mBaseDismantleCost;
	private int mBaseRegen;
	private int mBaseRegenTime;
	private int mBaseDismantleTime;
	private int mBaseTransferTime;
	private GLTexture mBaseImage;
	private Bitmap mBaseIcon;
	private ArrayList<GeneratorAttribute> mPowerUpgrades, mRangeUpgrades, mVoltageUpgrades;
	private String mName;
}
